/*
 *
 * This program is free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License version 2 as 
 * published by the Free Software Foundation.
 *
 * memory_pool.h is for what ...
 *
 * Version: ***: memory_pool.h  Fri Jul 22 21:26:02 2011 poponion Exp $
 *
 * Authors:
 *   Author poponion <huangcm85@gmail.com>
 *     -some work detail if you want 
 *
 */
#ifndef MEMORY_POOL_H
#define MEMORY_POOL_H
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

//This is a fix size memory pool
class MemoryPool
{
  class MemBlock
  {
  public:
  MemBlock(int32_t item_num, int32_t item_size):free_pos_(0),free_num_(item_num),item_size_(item_size)
    {
      int32_t index = 0;
      for(; index < item_num - 1; ++index)
      {
        *reinterpret_cast<int32_t *>(data_ + item_size * index) = index + 1;
      }
      *reinterpret_cast<int32_t *>(data_ + item_size * index ) = -1;
    }
    ~MemBlock()
    {
    }

    inline int32_t get_free_num()
    {
      return free_num_;
    }
    
    inline int32_t get_free_pos()
    {
      return free_pos_;
    }

    inline MemBlock * next()
    {
      return next_;
    }

    inline void set_next(MemBlock* next)
    {
      next_ = next;
    }
    
    inline void* data()
    {
      return reinterpret_cast<void*>(data_);
    }
    /*
     * Alloc memory free block buffer, if there are no free memory
     * return NULL, else return the pointer to the memory
     */
    void* alloc();
    
    /*
     * Set the memory which ptr pointer to reuseable
     */
    void free(void *ptr);
    
  private:
    int32_t free_pos_;
    int32_t free_num_;
    int32_t item_size_;
    MemBlock* next_;
    char data_[0];
  };
public:
  friend class MemBlock;
  MemoryPool(int item_size = 4096, int item_num = 1024);
  virtual ~MemoryPool();
    
  void * mem_alloc();

  /**
   * free a memory item
   * @param ptr pointer of the memory to free
   */
  void mem_free(void * ptr);

  /**
   * Destory memory pool
   * free all memory hold by the pool
   */
  void destory();
private:
  int32_t item_size_;
  int32_t item_num_;
  MemBlock* block_head_;
};
#endif
